iT邦幫忙

2024 iThome 鐵人賽

DAY 8
0
Kubernetes

異世界生存戰記:30天煉成GKE大師系列 第 8

Day8 Kubernetes 流量管理魔法棒 Nginx Ingress Controller

  • 分享至 

  • xImage
  •  

https://ithelp.ithome.com.tw/upload/images/20240922/201690171ZfPawliDn.png

前言

昨天我們使用 GCP 雲原生負載均衡的 Ingress,將 Loadbalancer 建立在 GKE 之外,本章將介紹 K8s 最多人使用的 Ingress Controller 。透過 Ingress,您可以簡單地管理入口流量,提高應用程序的可用性和安全性。在這篇文章中,我們將深入探討 Kubernetes Ingress 的概念、架構和使用方法,讓您更好地理解這個強大的入口控制器。

K8s Nginx Ingress 簡介

NGINX Ingress Controller 是 NGINX 和 NGINX Plus 的 Ingress Controller 實現,可以對 Websocket、gRPC、TCP 和 UDP 應用程式進行負載均衡。它支持標準的 Ingress 功能,例如基於內容的路由和 TLS/SSL 終止。一些 NGINX 和 NGINX Plus 功能可透過 Annotations 和 ConfigMap 資源作為 Ingress 資源的擴展使用。

可代理非 HTTP 請求

Nginx Ingress Controller 預設使用 HTTP 協議串連到後端服務,但同時提供了對多種後端協議的支援,其中比較常用的協議有 WebSocket、HTTPS 和 gRPC。關於支援的後端協議具體類型,請參見Backend Protocol

  • WebSocket:Nginx Ingress Controller 提供了對 WebSocket 的原生支援,您不需要進行任何配置即可轉寄 WebSocket 串連。如果您有持續較長的 WebSocket 串連,可以通過 Annotation 適當地調整後端串連的逾時時間,防止業務因為逾時而斷連。關於調整的具體操作,請參見Custom timeouts
  • HTTPS:針對使用 HTTPS 的後端服務,您可以在 Ingress 中添加nginx.ingress.kubernetes.io/backend-protocol:"HTTPS"的 Annotation 切換為 HTTPS 串連。
  • gRPC:gRPC 僅支援通過 TLS 連接埠訪問。因此,請確保您的業務通過 Nginx Ingress Controller 訪問 gRPC 服務時,使用的是加密的 TLS 連接埠。關於配置 gRPC 的具體操作,請參見 通過Ingress Controller實現gRPC服務訪問

本章節範例將針對 HTTP Request

使用 Helm Chart 來建立 Nginx Ingress Controller

$ helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
$ helm repo update
$ helm search repo ingress-nginx
NAME                            CHART VERSION   APP VERSION     DESCRIPTION
ingress-nginx/ingress-nginx     4.11.2          1.11.2          Ingress controller for Kubernetes using NGINX a...

$ helm pull ingress-nginx/ingress-nginx --version 4.11.2
$ tar zxvf ingress-nginx-4.11.2.tgz

修改 values.yaml,將需要修改的部分列下來

controller:
  config: 
    enable-real-ip: "true"
    use-forwarded-headers: "true"
    compute-full-forwarded-for: "true"
    proxy-real-ip-cidr: "0.0.0.0/0"
  electionID: "external-ingress-controller-leader"
# 將這次創建的nginx的ingressClass改成external-nginx
  ingressClassResource:
    name: external-nginx
    enabled: true
    controllerValue: "k8s.io/external-ingress-nginx"
  ingressClass: external-nginx
......省略......
  service:
	  enabled: true
    type: LoadBalancer
......省略......
# 如果有需要開其他Port在這裡加,假設有使用到 emqx 服務,那需要開啟的端口在此設定,如下
tcp: 
  1883: "emqx/emqx:1883" #mqtt
  8883: "emqx/emqx:8883" #mqttssl
  8083: "emqx/emqx:8083" #ws
  8084: "emqx/emqx:8084" #wss
  18083: "emqx/emqx:18083" #dashboard

使用 Helm 安裝 Nginx Ingress,安裝完成後輸入指令查看 Nginx Ingress Controller 的 Service 和 ingressclass 的狀態

$ helm upgrade --install external-nginx -f values.yaml . -n ingress-nginx --create-namespace

$ kubectl get svc -n ingress-nginx           
NAME                                        TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)                     AGE
external-nginx-ingress-nginx-controller     LoadBalancer   10.120.109.126   35.238.126.135   80:32690/TCP,443:31001/TCP  2m32s

$ kubectl get ingressclass 
NAME             CONTROLLER                      PARAMETERS   AGE
external-nginx   k8s.io/external-ingress-nginx   <none>       9m26s

helm install 後可以看到在 ingress-nginx Namespace 下,產生一組外部 IP(35.238.126.135) 給 external-nginx-ingress-nginx-controller 使用,同時 ingressclass 名字為 external-nginx

可以用昨天的那個 httpd 的服務做測試,建立一個 httpd 使用的 ingress 使用剛剛建立的 nginx,如果需要 WS, GRPCS, HTTPS SSL 證書等請求都是在 Annotations 添加設定,如以下 Yaml 中註解的字段,因為這是 HTTP 請求,所以先將 WS 和 GRPCS 註解掉

# httpd-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: httpd-nginx-ingress
  namespace: httpd
#  假設請求是WS, GRPCS...都是在Annotations添加設定,因為這是HTTP請求,所以先將WS和GRPCS註解掉
#  annotations:
#   nginx.ingress.kubernetes.io/backend-protocol: GRPCS
#   nginx.org/websocket-services: websocket-gateway-service
spec:
  ingressClassName: external-nginx
  rules:
    - host: demo-httpd-nginx.demoit.shop
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: httpd-service
                port:
                  number: 80

查看 httpd Ingress 狀態,kubectl get ingress -n httpd

$ kubectl get ingress -n httpd                                                        
NAME                  CLASS            HOSTS                    ADDRESS          PORTS   AGE
httpd-ing             <none>           demo-httpd.demoit.shop   34.128.184.181   80      14h
httpd-nginx-ingress   external-nginx   demo-httpd.demoit.shop   35.238.126.135   80      59s

會發現建立的 Ingress 的 ADDRESS IP 和剛建立 nginx-ingress service 的外部 IP 一樣都是 35.238.126.135

可以進入到 Cloud Load Balancing 查看和昨天建立的 Ingress 的不同之處,昨天建立的是 L7 的Loadbalance ,剛剛建立的是 L4 的 Loadbalance,對應到 K8s 內分別是 Ingress 和 Service 的差別

https://ithelp.ithome.com.tw/upload/images/20240922/20169017li5B2CnA3y.png

因為使用 Shared VPC,防火牆不會在 VPC 內自動加入,需要手動開啟,去到防火牆的頁面將剛剛建立的 Nginx Service Loadbalance IP(35.238.126.135) 加入防火牆,目標標記填入 Node Compute Engine 的標記,TCP Port 根據個人需求加入

https://ithelp.ithome.com.tw/upload/images/20240922/20169017JXf9tBrPFJ.png

接下來進到 Cloud DNS頁面,將 demo-httpd-nginx.demoit.shop 加入 A 紀錄 (35.238.126.135)才可以使用瀏覽器訪問此網址

https://ithelp.ithome.com.tw/upload/images/20240922/20169017jPEjvi3OEB.png

如果有部分服務因為資安考量,不想要暴露到外網,想要建立允許內網使用的 Internal Nginx 只需要將 values.yaml 以下字段加入,GCP 會產生內網 IP 的 L4 Loadbalance,重複以上步驟即可使用

controller:
  service:
    annotations: 
      cloud.google.com/load-balancer-type: "Internal"
      networking.gke.io/internal-load-balancer-allow-global-access: "true"

總結

今天講解了 GKE Nginx Ingress Controller,基本上不同雲的設置方法大同小異,只需要瞭解其基本原理,是使用 L4 Loadbalance 當作 Nginx Ingress 的 Service,將外部流量導入 Nginx Ingress Controller Pod 中進行流量轉發,如需設定 WebsocketGRPCCert-manager 證書白名單限流連線超時等插件,只需要在 Ingress.yaml 底下的 metadata.annotations 增加 nginx.org/...相關字段,因為篇幅有限,這裡就不進行示範了,詳細的做法可參考官方文件。

參考文件


上一篇
Day7 掌控流量入門 GKE NEG Service and Ingress
下一篇
Day9 告別網站危機 Google Trust Services 證書及External DNS
系列文
異世界生存戰記:30天煉成GKE大師30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言